package com.zl.gmadmin.controller.auth;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.ImmutableMap;
import com.wf.captcha.base.Captcha;
import com.zl.gmadmin.common.ApiResponse;
import com.zl.gmadmin.common.Status;
import com.zl.gmadmin.configuration.secutity.config.LoginCodeEnum;
import com.zl.gmadmin.configuration.secutity.config.LoginProperties;
import com.zl.gmadmin.exception.UserException;
import com.zl.gmadmin.payload.auth.LoginRequest;
import com.zl.gmadmin.utils.LogUtil;
import com.zl.gmadmin.utils.RedisUtils;
import com.zl.gmadmin.utils.SecurityUtils;
import com.zl.gmadmin.utils.jwt.JwtUtil;
import com.zl.gmadmin.vo.user.JwtResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangliang
 * @version 1.0
 * @date 2021/2/2 0:30
 */
@Api(tags = "授权")
@RestController
@RequestMapping("/auth")
public class AuthController {

    private final AuthenticationManager authenticationManager;

    private final JwtUtil jwtUtil;

    private final LoginProperties  loginProperties;

    private final RedisUtils redisUtils;


    public AuthController(AuthenticationManager authenticationManager, JwtUtil jwtUtil, LoginProperties loginProperties, RedisUtils redisUtils) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
        this.loginProperties = loginProperties;
        this.redisUtils = redisUtils;
    }

    @ApiOperation("用户登录")
    @PostMapping("/login")
    public ApiResponse login(@Valid @RequestBody LoginRequest loginRequest){
        LogUtil.debug("登录信息:"+ JSONUtil.toJsonStr(loginRequest));

        // 查询验证码
        String code = (String) redisUtils.get(loginRequest.getUuid());
        if (CharSequenceUtil.isBlank(code)) {
            throw new UserException(Status.CODE_HAS_EXPIRED);
        }
        if (CharSequenceUtil.isBlank(loginRequest.getCode()) || !loginRequest.getCode().equalsIgnoreCase(code)) {
            throw new UserException(Status.CODE_HAS_ERROR);
        }
        LogUtil.debug("123111111");
        // 清除验证码
        redisUtils.del(loginRequest.getUuid());

        Authentication authentication=null;
        try {
            System.out.println("验证");
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsernameOrEmailOrPhone(), loginRequest.getPassword()));
            System.out.println("验证失败");
        }catch (BadCredentialsException | InternalAuthenticationServiceException exception){
            LogUtil.debug("eeeeeeee:"+JSONUtil.toJsonStr(exception));
            throw  new UserException(Status.USERNAME_PASSWORD_ERROR);
        }
        SecurityContextHolder.getContext().setAuthentication(authentication);

//        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginRequest.getUsernameOrEmailOrPhone());
        String jwt=jwtUtil.createJWT(authentication,loginRequest.getRememberMe());

        System.out.println("登录成功:"+jwt);
        return ApiResponse.ofSuccess(new JwtResponse(jwt));
    }

    @ApiOperation("获取当前登录用户详情")
    @GetMapping("/userInfo")
    public ApiResponse userInfo(){
        return  ApiResponse.ofSuccess(SecurityUtils.getCurrentUser());
    }

    @ApiOperation("注销用户")
    @DeleteMapping("/logout")
    public ApiResponse logout(HttpServletRequest request){
        return ApiResponse.ofStatus(Status.LOGOUT);
    }

    @GetMapping("/code")
    @ApiOperation("获取登录验证码")
    public ApiResponse getCodeImage(){
        Captcha captcha =loginProperties.getCaptcha();
        String uuid= IdUtil.simpleUUID();

        //当验证码类型为 arithmetic时且长度 >= 2 时，captcha.text()的结果有几率为浮点型
        String captchaValue = captcha.text();
        String dian=".";
        if (captcha.getCharType() - 1 == LoginCodeEnum.arithmetic.ordinal() && captchaValue.contains(dian)) {
            captchaValue = captchaValue.split("\\.")[0];
        }
        // 保存
        redisUtils.set(uuid, captchaValue, loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES);
        // 验证码信息
        Map<String, Object> imgResult = ImmutableMap.of("img", captcha.toBase64(),"uuid", uuid);


        return ApiResponse.ofSuccess(imgResult);
    }



}
